package cn.tedu.ivos.audit.service.impl;

import cn.tedu.ivos.application.mapper.ApplicationMapper;
import cn.tedu.ivos.application.pojo.entity.Application;
import cn.tedu.ivos.audit.mapper.AuditMapper;
import cn.tedu.ivos.audit.pojo.dto.AuditQuery;
import cn.tedu.ivos.audit.pojo.dto.AuditSaveParam;
import cn.tedu.ivos.audit.pojo.entity.Audit;
import cn.tedu.ivos.audit.pojo.vo.AuditVO;
import cn.tedu.ivos.audit.service.AuditService;
import cn.tedu.ivos.base.enums.AuditStatusEnum;
import cn.tedu.ivos.user.mapper.UserMapper;
import cn.tedu.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;

/*  @Transactional是Spring提供的一个用于管理事务的注解,可以管理类或者方法上的事务行为
在对数据库做操作时,可以确保方法中的所有数据库作都在同一事务中执行,要么都成功,要么都失败 */
@Transactional
@Service
@Slf4j
public class AuditServiceImpl implements AuditService {
    @Autowired
    AuditMapper auditMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    ApplicationMapper  applicationMapper;
    @Override
    public void insertAudit(Application application){
        log.debug("生成申请单对应的审批单数据:application：{}",application);
        //1.获取审批入id集合[106,103]
        List<Long> userIdList=application.getAuditUserIdList();
        //2.遍历审批入id集合,有几个id就代表有几个审批人,就生成几条审批数据
        for(int i=0;i<userIdList.size();i++){
            Audit  audit=new Audit();
            //3.没置本条审批单的相关数据，一会新增到数据库里
            //3.1 设置批哪个申请单 申请单id
            audit.setApplicationId(application.getId());
            //3.2 设置谁来批 审批入id
            audit.setAuditUserId(userIdList.get(i));
            //3.3 设置审批次序
            audit.setAuditSort(i);
            //3.4 设置审批状态 待审批
            if(i==0){
                audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
            }else{
                audit.setAuditStatus(AuditStatusEnum.PENDING.getCode());
            }
            //3.5 设置新增时间
            audit.setCreateTime(new Date());
            //4.将本条审批数据插入到数据库中
            auditMapper.insert(audit);

        }
    }

    @Override
    public List<AuditVO> selectAuditByApplicationId(Long id) {
        log.debug("查询申请单对应的审批单数据:id：{}",id);
        return auditMapper.selectAuditByApplicationId(id);
    }

    @Override
    public List<AuditVO> selectAudit(AuditQuery auditQuery) {
        log.debug("查询审批单数据:auditQuery：{}",auditQuery);
        List<AuditVO> list=auditMapper.selectAudit(auditQuery);
        for(int i=0;i<list.size();i++){
            AuditVO auditVO=list.get(i);
            assignAuditUserList(auditVO);
            log.debug("查询审批-------------------单数据结果：{}",auditVO);
        }
        return list;
    }

    @Override
    public void updateAudit(AuditSaveParam auditSaveParam) {
        log.debug("更新审批单数据:auditSaveParam：{}",auditSaveParam);
        Audit audit=new Audit();
        BeanUtils.copyProperties(auditSaveParam,audit);
        audit.setUpdateTime(new Date());
        auditMapper.update(audit);
        //继续更新此审批单对应的申请单
        Application application=new Application();
        application.setId(audit.getApplicationId());
        application.setUpdateTime(new Date());
        /* 判断前端的审批操作是"通过"还是"驳回"，分头出来 */
        if(audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())){//通过
            /* 继续查其他的审批单：与刚刚更新的那条审批单批同一个申请单 */
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            Integer count=auditMapper.selectRestAuditCount(auditQuery);
            if(count>0){//还有未批的审批单
                auditQuery.setAuditSort(audit.getAuditSort()+1);
                List<AuditVO> auditVOList=auditMapper.selectAudit(auditQuery);
                if(auditVOList!=null && auditVOList.size()>0){
                    AuditVO auditVO = auditVOList.get(0);
                    //创建第2个审就空对象用于更新
                    Audit audit2 = new Audit();
                    //给这个空对象封装更新的条件
                    audit2.setId(auditVO.getId());
                    audit2.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
                    audit2.setUpdateTime(new Date());
                    auditMapper.update(audit2);
                }
            }else{//刚刚更新的审批单就是最后一条,没有未批的审批单
                //设置申请单状态为"已事校"(后缝分配用车)
                application.setStatus(AuditStatusEnum.AUDITED.getCode());
                applicationMapper.update(application);
            }
        }else {//驳回
            AuditQuery  auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
            if (auditVOList !=null && auditVOList.size() > 0){
                for(int i=0;i<auditVOList.size();i++){
                    AuditVO auditVO = auditVOList.get(i);
                    if(auditVO.getAuditStatus().equals(AuditStatusEnum.PENDING.getCode())){
                        auditMapper.deleteById(auditVO.getId());
                    }
                }
            }
            application.setStatus(AuditStatusEnum.REJECT.getCode());
            application.setRejectReason(auditSaveParam.getRejectReason());
            applicationMapper.update(application);
        }
    }

    private void assignAuditUserList(AuditVO auditVO) {
        List<String> auditUsernameList = new ArrayList<>();//准备姓名空集合
        List<Long> auditUserIdList = new ArrayList<>();//准备id空集合
        //根据审批单VO中的申请单id,查出批当前申请单的所有审批单
        List<AuditVO> auditVOList = auditMapper.selectAuditByApplicationId(auditVO.getApplicationId());
        //遍历每一个审批单,获取每个审批人的id与姓名
        for(int i = 0; i < auditVOList.size(); i++){
            Long userId = auditVOList.get(i).getAuditUserId();//获取当前审批单VO中的审批人id
            auditUserIdList.add(userId);//把审批人id装空集合里
            UserVO user = userMapper.selectById(userId);//根据id查询审批人
            auditUsernameList.add(user.getUsername());//把审批人姓名装空集合里
        }
        StringJoiner stringJoiner = new StringJoiner(",");//准备拼接工具
        for(String username : auditUsernameList){//遍历姓名集合
            stringJoiner.add(username);//依次将每个审批人姓名装入StringJoiner中
        }
        auditVO.setAuditUserIdList(auditUserIdList);//给申请单VO设置审批人id集合与审批人姓名字符串(补全数据)
        auditVO.setAuditUsernameList(stringJoiner.toString());
    }
}
